package com.exposit.books.service;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.exposit.books.dao.BookDAO;
import com.exposit.books.dao.BuyerDAO;
import com.exposit.books.dao.CommentDAO;
import com.exposit.books.dao.OrderDAO;
import com.exposit.books.domain.Book;
import com.exposit.books.domain.Buyer;
import com.exposit.books.domain.Comment;
import com.exposit.books.domain.Order;

@Service
@Transactional
public class UserServiceImpl implements UserService {

	@Autowired
	private BuyerDAO buyerDAO;
	
	@Autowired
	private BookDAO bookDAO;
	
	@Autowired
	private OrderDAO orderDAO;
	
	@Autowired
	private CommentDAO commentDAO;
	
	@Override
	public Buyer getBuyerById(Long id) {
		return buyerDAO.getById(id);
	}

	@Override
	public List<Book> getAllBooks() {
		return bookDAO.getAll();
	}

	@Override
	public void newOrder(Buyer buyer, Book book, Long count, String address, String payment) {
		
		Order order;
		if (count <= book.getCount())
		{
			order = new Order(count, address, payment, 1L);
			order.setBook(book);
			order.setBuyer(buyer);
			book.setCount(book.getCount()-count);
		}
		else if (book.getCount() == 0)
		{
			order = new Order(count, address, payment, -1L);
			order.setBook(book);
			order.setBuyer(buyer);
		}
		else
		{
			order = new Order(book.getCount(), address, payment, 1L);
			Order preOrder = new Order(count-book.getCount(), address, payment, -1L);
			book.setCount(0L);
			order.setBook(book);
			preOrder.setBook(book);
			order.setBuyer(buyer);
			preOrder.setBuyer(buyer);
			orderDAO.save(preOrder);
		}

		orderDAO.save(order);
	}

	@Override
	public void cancelOrder(Order order) throws Exception {
		if (order.getStatus() == 0)
			throw new Exception("The order has been treated.");
		if (order.getStatus() == 1)
		{
			Book book = order.getBook();
			book.setCount(book.getCount()+order.getCount());
			bookDAO.update(book);
			orderDAO.delete(order);
			return;
		}
		orderDAO.delete(order);
	}

	@SuppressWarnings("deprecation")
	public Long returnBook(Order order, Long count) throws Exception
	{
		if (order.getStatus() != 0)
			throw new Exception("Sorry, the order has not been processed.");
		if (order.getCount()<count)
			throw new Exception("Sorry, but you have not so many books.");
		Date date = order.getDate();
		date.setMonth(order.getDate().getMonth()+1);
		order.setCount(order.getCount()-count);
		Book temp;
		if ((temp = isOldBookExist(order.getBook())) != null)
		{
			temp.setCount(temp.getCount() + count);
			bookDAO.update(temp);
		}
		else
		{
			Book book = order.getBook().clone();
			book.setStatus(-1L);
			book.setCount(count);
			book.setOrders(null);
			book.setRetailPrice(book.getRetailPrice()/2);
			bookDAO.save(book);
		}
		
		if (date.after(new Date()))
		{
			return order.getBook().getRetailPrice()/10*7;
		}
		else
		{
			return order.getBook().getRetailPrice()/10*4;
		}		
	}

	private Book isOldBookExist(Book book)
	{
		List<Book> books= bookDAO.getBookByName(book.getName());
		for (Book x : books)
			if (x.getStatus()== -1)
				return x;
		return null;
	}

	@Override
	public List<Order> getOrders(Buyer buyer) {
		return buyer.getOrders();
	}

	@Override
	public void addComment(Buyer buyer, Book book, String text) {
		Comment comment = new Comment(text);
		comment.setBook(book);
		comment.setBuyer(buyer);
		commentDAO.save(comment);
	}

	@Override
	public void deleteComment(Comment comment) {
		commentDAO.delete(comment);
	}
}
